package com.one.rope.mvp.web.common.filter;

import com.alibaba.fastjson.JSONObject;
import com.one.rope.mvp.basecore.exception.BusinessDataException;
import com.one.rope.mvp.web.common.auth.TokenManager;
import com.one.rope.mvp.web.common.auth.UserInfo;
import com.one.rope.mvp.web.common.auth.UserLoginUtil;
import com.one.rope.mvp.basecore.bean.ResponseObject;
import com.one.rope.mvp.basecore.bean.UserBusinessMessage;
import com.one.rope.mvp.web.common.jwt.PayloadBean;
import com.one.rope.mvp.web.common.util.SpringUtil;
import com.one.rope.mvp.web.config.GlobalConfig;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.util.WebUtils;

/**
 * @author Weijian.liu
 * @desc 小程序户登录过滤器
 * @date 2020/02/19
 */
@Slf4j
public class UserLoginFilter extends UserFilter {

  @Override
  protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue){
    HttpServletRequest servletRequest = (HttpServletRequest) request;
    if ("options".equalsIgnoreCase(servletRequest.getMethod())) {
      return true;
    }
    TokenManager tokenManager = SpringUtil.getBean(TokenManager.class);
    String userLoginToken = getToken(request);
    if (StringUtils.isBlank(userLoginToken)) {
      return false;
    }
    PayloadBean payloadBean = UserLoginUtil.auth(userLoginToken);
    if (null == payloadBean) {
      return false;
    } else if (payloadBean.hasExpires()) {
      return false;
    }
    try {
      UserInfo userInfo = tokenManager.getUserLoginInfo(userLoginToken);
      if (null == userInfo) {
        return false;
      }
      UserLoginUtil.initThreadContext(userInfo);
    }catch (Exception e){
      log.error("登录认证异常", e);
      return false;
    }

    return true;
  }

  /**
   * 根据参数或者header获取token
   */
  public static String getToken(ServletRequest request) {
    HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
    String loginToken = httpServletRequest.getParameter(GlobalConfig.TOKEN_NAME);
    if (StringUtils.isBlank(loginToken)) {
      loginToken = httpServletRequest.getHeader(GlobalConfig.TOKEN_NAME);
    }
    return loginToken;
  }

  @Override
  protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
    HttpServletRequest servletRequest = (HttpServletRequest) request;
    if ("options".equalsIgnoreCase(servletRequest.getMethod())) {
      return true;
    }
    String loginToken = getToken(request);
    if (StringUtils.isBlank(loginToken)) {
      writeResponse(WebUtils.toHttp(response), JSONObject.toJSONString(ResponseObject.userFailure(UserBusinessMessage.NOT_LOGIN_IN)));
      return false;
    }

    writeResponse(WebUtils.toHttp(response), JSONObject.toJSONString(ResponseObject.userFailure(UserBusinessMessage.TOKEN_IS_EXPIRE)));
    return false;
  }

  public static void writeResponse(HttpServletResponse response, String json) {
    try {
      response.setHeader("Access-Control-Allow-Origin", "*");
      response.setHeader("Access-Control-Allow-Methods", "*");
      response.setContentType("application/json;charset=UTF-8");
      response.getWriter().write(json);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception)
      throws Exception {
    UserLoginUtil.clear();
  }
}
